#include "stdafx.h"
#include <MyControls/ZoomEdit.h>
#include <MyControls/Resource.h>
#include <MyControls/App.h>
#include <cmath>
#include <math/round.h>
#include <sstream>
#include <iomanip>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace My {

void ZoomTextEdit::SetView(ZoomView * pView)
{
	if (pView != m_pView) {
		m_pView = pView;
		SetEnabled(m_pView != 0);
	}
}

bool ZoomTextEdit::GetText(String & s)
{
	if (m_pView == 0)
		return false;
	int value = round(m_pView->GetScale() * 100);
	std::ostringstream out;
	out << value << "%";
	s = out.str();
	return true;
}

void ZoomTextEdit::SetText(const String & s)
{
	if (m_pView == 0)
		return;
	std::istringstream in(s);
	double value;
	in >> value;
	if (in.fail())
		return;
	std::string units = "%";
	if (!in.eof())
		in >> units;
	if (in.fail())
		return;
	if (!in.eof())
		return;
	if (units != "%")
		return;
	m_pView->SetScale(float(value / 100));
}

ZoomTextEdit::ZoomTextEdit() 
	: m_pView(0)
{
	SetEnabled(false);
}

void ZoomTextEdit::UpdateScale()
{
	Invalidate();
}

void ZoomTextEdit::HandleUpdateUI()
{
	UpdateScale();
}

// ZoomEdit

struct ZoomEditMenuItem 
{
	const char *	name;
	double			value;
};

static ZoomEditMenuItem _items[] = {
	{"25%", 0.25},
	{"50%", 0.5},
	{"100%", 1.0},
	{"200%", 2.0},
	{"400%", 4.0},
	{"800%", 8.0},
	{"1600%", 16.0}
};

ZoomEdit::ZoomEdit() 
	: m_pView(0)
{
	m_Down.Load("DROPDOWN_BUTTON", "DROPDOWN_BUTTON_MASK");
	m_Grayed.Load("DROPDOWN_BUTTON", "DROPDOWN_BUTTON_MASK");
	VERIFY (m_hCurHandClick = AfxGetApp()->LoadCursor("CURSORHANDCLICK"));
	Add(&m_TextEdit);
	SetEnabled(false);
}

String ZoomEdit::Hint() const
{
	return GetApp().LoadString(IDS_ZOOM);
}

void ZoomEdit::SetView(ZoomView * pView)
{
	if (pView != m_pView) {
		m_pView = pView;
		m_TextEdit.SetView(pView);
		SetEnabled(m_pView != 0);
	}
}

void ZoomEdit::DropDown()
{
	if (m_pView == 0)
		return;

	CMenu menu;
	VERIFY(menu.CreatePopupMenu());

	int index;
	unsigned int i;
	unsigned int count = sizeof(_items) / sizeof(ZoomEditMenuItem);

	index = -1;
	for (i = 0; i < count; ++i)
		if (_items[i].value == m_pView->GetScale()) {
			index = i;
			break;
		}

	for (i = 0; i < count; ++i) {
		UINT nFlags = MF_STRING;
		if (i == index)
			nFlags |= MF_CHECKED;
		menu.AppendMenu(nFlags, 1 + i, _items[i].name);
	}

	menu.AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)0);
	menu.AppendMenu(MF_STRING, 1000, "Fit on Screen");

	CPoint p = ClientToScreen(CPoint(m_DownRect.right, m_DownRect.bottom));

	index =	::TrackPopupMenu(menu.m_hMenu, TPM_RIGHTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,
			p.x, p.y, 0, GetWindow()->m_hWnd, 0);
	ReleaseMouse();

	if (index != 0) {
		if (index == 1000)
			m_pView->ZoomFit();
		else
			m_pView->Zoom(float(_items[index - 1].value));
		Invalidate();
	}
}

void ZoomEdit::LayoutControls()
{
	CRect rClient = ClientRect();

	m_DownRect = rClient;
	m_DownRect.left = m_DownRect.right - 4 - m_Down.Width() - 4;

	CRect rEdit(rClient);
	rEdit.right = m_DownRect.left;
	m_TextEdit.SetBounds(rEdit);
}

void ZoomEdit::HandlePaint(CDC * pDC, const CRect & r)
{
	CRect rClient = ClientRect();

	COLORREF cF = GetSysColor(COLOR_BTNFACE);
	CBrush bFace(cF);
	pDC->FillRect(&r, &bFace);

	if (rClient.Width() > m_DownRect.Width()) {
		CPoint p = m_DownRect.CenterPoint();
		if (ControlEnabled(this))
			m_Down.Draw(pDC, m_DownRect);
		else
			m_Grayed.Draw(pDC, m_DownRect);
	}
}

void ZoomEdit::HandleLeftDown(unsigned int flags, const CPoint & p)
{
	Control::HandleLeftDown(flags, p);
	if (m_DownRect.PtInRect(p))
		DropDown();
}

void ZoomEdit::HandleLeftDoubleClick(unsigned int flags, const CPoint & p)
{
	// Simulate a normal click...
	HandleLeftDown(flags, p);
	Update();
	Sleep(100);
	HandleLeftUp(flags, p);
}

bool ZoomEdit::HandleCursor(unsigned int flags, const CPoint & p)
{
	if (m_DownRect.PtInRect(p))
		SetCursor(m_hCurHandClick);
	else
		SetCursor(::LoadCursor(NULL, IDC_ARROW));
	return true;
}

} // My
